iT邦幫忙

2023 iThome 鐵人賽

DAY 2
0
Web 3

以 Python 進入以太坊虛擬機 (EVM) 的幻想境界系列 第 2

虛擬境界 2:OPCODES 運作

  • 分享至 

  • xImage
  •  

在介紹 Opcodes 前,先介紹一支 solidity 程式是如何執行的

我們先寫一組簡單的 solidity code

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract HelloWorld {
    string public hello = "Hello World!";
}

compile (或用 remix 編譯)

# 用 docker compile
docker pull ethereum/solc:0.8.20
docker run --rm ethereum/solc:0.8.20

https://ithelp.ithome.com.tw/upload/images/20230917/201309262yOTHYGoEE.png

可以編譯成以下 bytecode 這些 bytecode 就是

60806040526040518060400160405280600c81526020017f48656c6c6f20576f726c642100000000000000000000000000000000000000008152505f90816100479190610293565b50348015610053575f80fd5b50610362565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806100d457607f821691505b6020821081036100e7576100e6610090565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026101497fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261010e565b610153868361010e565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61019761019261018d8461016b565b610174565b61016b565b9050919050565b5f819050919050565b6101b08361017d565b6101c46101bc8261019e565b84845461011a565b825550505050565b5f90565b6101d86101cc565b6101e38184846101a7565b505050565b5b81811015610206576101fb5f826101d0565b6001810190506101e9565b5050565b601f82111561024b5761021c816100ed565b610225846100ff565b81016020851015610234578190505b610248610240856100ff565b8301826101e8565b50505b505050565b5f82821c905092915050565b5f61026b5f1984600802610250565b1980831691505092915050565b5f610283838361025c565b9150826002028217905092915050565b61029c82610059565b67ffffffffffffffff8111156102b5576102b4610063565b5b6102bf82546100bd565b6102ca82828561020a565b5f60209050601f8311600181146102fb575f84156102e9578287015190505b6102f38582610278565b86555061035a565b601f198416610309866100ed565b5f5b828110156103305784890151825560018201915060208501945060208101905061030b565b8683101561034d5784890151610349601f89168261025c565b8355505b6001600288020188555050505b505050505050565b6102138061036f5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c806319ff1d211461002d575b5f80fd5b61003561004b565b6040516100429190610160565b60405180910390f35b5f8054610057906101ad565b80601f0160208091040260200160405190810160405280929190818152602001828054610083906101ad565b80156100ce5780601f106100a5576101008083540402835291602001916100ce565b820191905f5260205f20905b8154815290600101906020018083116100b157829003601f168201915b505050505081565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561010d5780820151818401526020810190506100f2565b5f8484015250505050565b5f601f19601f8301169050919050565b5f610132826100d6565b61013c81856100e0565b935061014c8185602086016100f0565b61015581610118565b840191505092915050565b5f6020820190508181035f8301526101788184610128565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806101c457607f821691505b6020821081036101d7576101d6610180565b5b5091905056fea2646970667358221220332b69fc79033f9063e1379e1102d13deb68163fdd8c398a20ecc0c6858351ee64736f6c63430008150033

再來將這組 contract deploy 到 remix 的 VM 上

https://ithelp.ithome.com.tw/upload/images/20230917/20130926aJNx8MHSNI.png

接下來我們會利用到旁邊那個 Debug 按鈕

https://ithelp.ithome.com.tw/upload/images/20230917/20130926ILgWVV1H8O.png

再來按下 step into,可以跑到我們第一行 bytecode ,可以看到是 60,而 0x60 的 Opcodes 正是 PUSH1,所以 6080就是將 80 推入 stack 中,可以看到下圖的 stack 0 會有個 0x80 的值儲存在裡面,所以我們可以看到這堆 bytecode 就是 EVM 的機器語言,在 EVM 會將這些 code 根據 Opcode 執行不同行為或運算,而每個 Opcode 都有不同的行為,接下來就來介紹 Opcode

https://ithelp.ithome.com.tw/upload/images/20230917/201309261FwbFF6KZF.png

https://ithelp.ithome.com.tw/upload/images/20230917/20130926EV1niHMety.png

在實際交易執行就會由下圖的方式做交易,先由 EOA 做訊息傳遞,而訊息內容就是先將 function 做 sha3 來讓 EVM 從 storage 讀取合約帳戶狀態並執行內部 EVM bytecode 並執行或運算來改變狀態.

https://ithelp.ithome.com.tw/upload/images/20230917/20130926pms9h1JMDU.png

Opcode 介紹

如上所述,以太坊的 stack 會根據這些編譯過後的 bytecode 來運作,與大多數虛擬機採用的二進制表示法不同,為便於記憶與可讀性,EVM 所有的 Opcode 都以1 byte 表示,並附加一個名稱,而每個指令會介於 0~255(00 ~ FF) 之間,如同上面的 bytecode 所示,EVM 會讀取上述的指令並執行,如果指令無法執行就會被 revert

Opcode 分類

  • stack: 可用這類指令控制 stack,包含 push 和 pop,可控制 stack 內部資料
  • arithmetic: 執行運算,加減乘除和餘數等功能
  • comparison: 用於比較堆疊的兩個數
  • bitwise: 位元運算子,對 bit 做運算
  • memory: 操作 EVM 的記憶體,將 stack 資料保存到記憶體,讀取或寫入
  • storage: 讀取 EVM 帳戶儲存,將數據讀取到 stack,並將數據存到儲存中
  • control flow: 可以控制 EVM 的功能,比如 JUMP
  • context: 獲取區塊的上下文資訊

接下來下幾堂課就是開始介紹如何實現這些 opcode

參考資料

https://www.evm.codes/


上一篇
虛擬境界 1:介紹以太坊虛擬機 (EVM)
下一篇
虛擬境界 3:Stack (PUSH & POP)
系列文
以 Python 進入以太坊虛擬機 (EVM) 的幻想境界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言